import cv2
import numpy as np
import random
from math import *


def drawGraph(img, datalists, colors, margin=50):
    graph = img.copy()
    h, w, _ = graph.shape
    # 确定图像范围和比例
    minx, maxx, miny, maxy = findaRange(datalists[0])
    for i in range(1, len(datalists)):
        minx_, maxx_, miny_, maxy_ = findaRange(datalists[i])
        minx = min(minx, minx_)
        maxx = max(maxx, maxx_)
        miny = min(miny, miny_)
        maxy = max(maxy, maxy_)
    minx, maxx, numx, deltax, lg10x = roundRange(minx, maxx)
    miny, maxy, numy, deltay, lg10y = roundRange(miny, maxy)
    dx, dy = (w - 2 * margin) / (numx), (h - 2 * margin) / (numy)
    # 绘制坐标轴
    color = [255, 255, 255]
    thickness = 1
    cv2.rectangle(graph, (margin, margin), (w - margin, h - margin), color, thickness)
    ## 横坐标
    for i in range(numx):
        x = margin + int(dx * i)
        y = h - margin
        cv2.line(graph, (x, y), (x, y + 5), color, thickness)
        cv2.putText(
            graph,
            fixnum2Str(minx + deltax * i),
            (x, y + 15),
            cv2.FONT_HERSHEY_SIMPLEX,
            0.5,
            color,
        )
    ## 纵坐标
    for i in range(numy):
        x = margin
        y = h - margin - int(dy * i)
        cv2.line(graph, (x, y), (x - 5, y), color, thickness)
        cv2.putText(
            graph,
            fixnum2Str(miny + deltay * i),
            (x - 40, y),
            cv2.FONT_HERSHEY_SIMPLEX,
            0.5,
            color,
        )
    # 颜色处理
    if len(colors) < len(datalists):
        colors = rndColors(len(datalists))
    # 绘制曲线
    for i in range(len(datalists)):
        datalist = datalists[i]
        prevx = margin + int((datalist[0][0] - minx) / deltax * dx)
        prevy = h - margin - int((datalist[0][1] - miny) / deltay * dy)
        for j in range(1, len(datalist)):
            x = margin + int((datalist[j][0] - minx) / deltax * dx)
            y = h - margin - int((datalist[j][1] - miny) / deltay * dy)
            cv2.line(graph, (prevx, prevy), (x, y), colors[i], 1)
            prevx, prevy = x, y
    return graph


def findaRange(mat):
    minx = np.array(mat)[:, 0].min()
    maxx = np.array(mat)[:, 0].max()
    miny = np.array(mat)[:, 1].min()
    maxy = np.array(mat)[:, 1].max()
    return minx, maxx, miny, maxy


def roundRange(a, b):
    if a == b:
        a, b = 0, 1
    r = b - a
    lg = int(log10(r)) - 1
    n = int(r / (10**lg))
    if n < 10:
        delta = 10**lg
    if n >= 10 and n < 40:
        delta = 10 ** (lg) * 2
    if n >= 40 and n < 70:
        delta = 10 ** (lg) * 5
    if n >= 70:
        delta = 10 ** (lg) * 10
    n = int(r / delta) + 2
    a = int(a / delta - 1) * delta
    b = int(b / delta + 1) * delta
    return a, b, n, delta, lg


def fixnum2Str(n):
    if n == 0:
        return "0"
    if log10(abs(n)) < 4 and log10(abs(n)) > -4:
        return str(n)[:5]
    return "{:.1e}".format(n)


def rndColors(n):
    lis = []
    for i in range(n):
        lis.append(
            (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
        )
    return lis
